const fs = require("fs-extra");
const path = require("node:path");
const ignore = require("ignore");

// Central default ignore patterns for discovery and filtering.
// These complement .gitignore and are applied regardless of VCS presence.
const DEFAULT_PATTERNS = [
  // Project/VCS
  "**/.bmad-core/**",
  "**/.git/**",
  "**/.svn/**",
  "**/.hg/**",
  "**/.bzr/**",
  // Package/build outputs
  "**/node_modules/**",
  "**/bower_components/**",
  "**/vendor/**",
  "**/packages/**",
  "**/build/**",
  "**/dist/**",
  "**/out/**",
  "**/target/**",
  "**/bin/**",
  "**/obj/**",
  "**/release/**",
  "**/debug/**",
  // Environments
  "**/.venv/**",
  "**/venv/**",
  "**/.virtualenv/**",
  "**/virtualenv/**",
  "**/env/**",
  // Logs & coverage
  "**/*.log",
  "**/npm-debug.log*",
  "**/yarn-debug.log*",
  "**/yarn-error.log*",
  "**/lerna-debug.log*",
  "**/coverage/**",
  "**/.nyc_output/**",
  "**/.coverage/**",
  "**/test-results/**",
  // Caches & temp
  "**/.cache/**",
  "**/.tmp/**",
  "**/.temp/**",
  "**/tmp/**",
  "**/temp/**",
  "**/.sass-cache/**",
  // IDE/editor
  "**/.vscode/**",
  "**/.idea/**",
  "**/*.swp",
  "**/*.swo",
  "**/*~",
  "**/.project",
  "**/.classpath",
  "**/.settings/**",
  "**/*.sublime-project",
  "**/*.sublime-workspace",
  // Lockfiles
  "**/package-lock.json",
  "**/yarn.lock",
  "**/pnpm-lock.yaml",
  "**/composer.lock",
  "**/Pipfile.lock",
  // Python/Java/compiled artifacts
  "**/*.pyc",
  "**/*.pyo",
  "**/*.pyd",
  "**/__pycache__/**",
  "**/*.class",
  "**/*.jar",
  "**/*.war",
  "**/*.ear",
  "**/*.o",
  "**/*.so",
  "**/*.dll",
  "**/*.exe",
  // System junk
  "**/lib64/**",
  "**/.venv/lib64/**",
  "**/venv/lib64/**",
  "**/_site/**",
  "**/.jekyll-cache/**",
  "**/.jekyll-metadata",
  "**/.DS_Store",
  "**/.DS_Store?",
  "**/._*",
  "**/.Spotlight-V100/**",
  "**/.Trashes/**",
  "**/ehthumbs.db",
  "**/Thumbs.db",
  "**/desktop.ini",
  // XML outputs
  "**/flattened-codebase.xml",
  "**/repomix-output.xml",
  // Images, media, fonts, archives, docs, dylibs
  "**/*.jpg",
  "**/*.jpeg",
  "**/*.png",
  "**/*.gif",
  "**/*.bmp",
  "**/*.ico",
  "**/*.svg",
  "**/*.pdf",
  "**/*.doc",
  "**/*.docx",
  "**/*.xls",
  "**/*.xlsx",
  "**/*.ppt",
  "**/*.pptx",
  "**/*.zip",
  "**/*.tar",
  "**/*.gz",
  "**/*.rar",
  "**/*.7z",
  "**/*.dylib",
  "**/*.mp3",
  "**/*.mp4",
  "**/*.avi",
  "**/*.mov",
  "**/*.wav",
  "**/*.ttf",
  "**/*.otf",
  "**/*.woff",
  "**/*.woff2",
  // Env files
  "**/.env",
  "**/.env.*",
  "**/*.env",
  // Misc
  "**/junit.xml",
];

async function readIgnoreFile(filePath) {
  try {
    if (!await fs.pathExists(filePath)) return [];
    const content = await fs.readFile(filePath, "utf8");
    return content
      .split("\n")
      .map((l) => l.trim())
      .filter((l) => l && !l.startsWith("#"));
  } catch (err) {
    return [];
  }
}

// Backward compatible export matching previous signature
async function parseGitignore(gitignorePath) {
  return readIgnoreFile(gitignorePath);
}

async function loadIgnore(rootDir, extraPatterns = []) {
  const ig = ignore();
  const gitignorePath = path.join(rootDir, ".gitignore");
  const patterns = [
    ...await readIgnoreFile(gitignorePath),
    ...DEFAULT_PATTERNS,
    ...extraPatterns,
  ];
  // De-duplicate
  const unique = Array.from(new Set(patterns.map((p) => String(p))));
  ig.add(unique);

  // Include-only filter: return true if path should be included
  const filter = (relativePath) => !ig.ignores(relativePath.replace(/\\/g, "/"));

  return { ig, filter, patterns: unique };
}

module.exports = {
  DEFAULT_PATTERNS,
  parseGitignore,
  loadIgnore,
};
